package org.quickserver.util.data;

public class Crc16 {

    /**
     * crc16-ccitt-false加/解密（四字节）
     *
     * @param bytes
     * @return
     */
    public static int crc16(byte[] bytes) {
        return crc16(bytes, bytes.length);
    }

    /**
     * crc16-ccitt-false加/解密（四字节）
     *
     * @param bytes -字节数组
     * @return
     */
    public static int crc16(byte[] bytes, int len) {
        int crc = 0xFFFF;
        for (int j = 0; j < len; j++) {
            crc = ((crc >>> 8) | (crc << 8)) & 0xffff;
            crc ^= (bytes[j] & 0xff);// byte to int, trunc sign
            crc ^= ((crc & 0xff) >> 4);
            crc ^= (crc << 12) & 0xffff;
            crc ^= ((crc & 0xFF) << 5) & 0xffff;
        }
        crc &= 0xffff;
        return crc;
    }

    /**
     * crc16-ccitt-false加/解密（四字节）
     *
     * @param bytes
     * @return
     */
    public static int crc16(byte[] bytes, int start, int len) {
        int crc = 0xFFFF;
        for (; start < len; start++) {
            crc = ((crc >>> 8) | (crc << 8)) & 0xffff;
            crc ^= (bytes[start] & 0xff);// byte to int, trunc sign
            crc ^= ((crc & 0xff) >> 4);
            crc ^= (crc << 12) & 0xffff;
            crc ^= ((crc & 0xFF) << 5) & 0xffff;
        }
        crc &= 0xffff;
        return crc;
    }

    /**
     * crc16-ccitt-false加/解密
     *
     * @param bytes
     * -字节数组
     * @return
     */
    public static short crc16_short(byte[] bytes) {
        return crc16_short(bytes, 0, bytes.length);
    }

    /**
     * crc16-ccitt-false加/解密（计算从0位置开始的len长度）
     *
     * @param bytes
     * -字节数组
     * @param len
     * -长度
     * @return
     */
    public static short crc16_short(byte[] bytes, int len) {
        return (short) crc16(bytes, len);
    }

    /**
     * crc16-ccitt-false加/解密（两字节）
     *
     * @param bytes
     * @return
     */
    public static short crc16_short(byte[] bytes, int start, int len) {
        return (short) crc16(bytes, start, len);
    }



    public static String getCRC2(byte[] bytes) {
        int CRC = 0x0000ffff;
        int POLYNOMIAL = 0x0000a001;

        int i, j;
        for (i = 0; i < bytes.length; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
        return Integer.toHexString(CRC);
    }

    public static void main(String[] args) throws Exception {
        //7D040A05051200001B047E
        //String [] a1=dataProcessing.strsToStrs2("404001000102180A0F0F0614000000000000468C68F80D002B00027A01C80000E90300000200010400000000CDCCCC3D0FB5DA31CDA8B5C0B5CDCFDEB1A8BEAF1E0A0F0F0614B02323");
        byte[] bytes = dataProcessing.hexStrToByteArray("441938363739303030343730383336353700031101040000001F081F000400007FFF7FFF7FFF7FFF3F80000041F000000000000000000000000000000000000000000000");
        String crc = getCRC2(bytes);
        System.out.println(crc);
    }

}
